#include <stdio.h>
#include <stdlib.h>


#include "sqstack.h"



static void compute(sqstack *snum,datatype *op)
{
	datatype n1,n2,n;
	st_pop(snum,&n2);
	st_pop(snum,&n1);

	switch(*op)
	{
		case '+':
			n = n1 + n2;
			break;
		case '-':
			n = n1 - n2;
			break;
		case '*':
			n = n1 * n2;
			break;
		case '/':
			n = n1 / n2;
			break;
		default:
			break;
	}
	st_push(snum,&n);
	return ;
}

static void deal_bracket(sqstack *snum,sqstack *sop) // 处理右括号
{
	datatype old_op;
	st_top(sop,&old_op);
	

	while(old_op != '(')
	{
		st_pop(sop,&old_op);
		compute(snum,&old_op);//运算
		st_top(sop,&old_op);
	}
	st_pop(sop,&old_op);//弹出左括号
	return ;
}
static int get_pri(datatype *op)
{
	int num = 0;
	switch(*op)
	{
		case '(':
			return 0;
		case '+':
		case '-':
			return 1;
		case '*':
		case '/':
			return 2;
	}
}

static void deal_op(sqstack *snum,sqstack *sop,datatype op)
{
	datatype old_op;
	if(st_isempty(sop) || op == '(')
	{
		st_push(sop,&op);
		return ;
	}
	
	st_top(sop,&old_op);
	
	if(get_pri(&op) > get_pri(&old_op))
	{
		st_push(sop,&op);
		return ;
	}


	while(get_pri(&op) <= get_pri(&old_op))
	{
		st_pop(sop,&old_op);
		compute(snum,&old_op);
		if (st_isempty(sop))
			break;
		st_top(sop,&old_op);
	}
	st_push(sop,&op);
}

int main(void)
{

	int i = 0;
	char str[] = "(11+3)*2-5";
	sqstack *snum,*sop;
	int value = 0;
	int flag = 0;
	snum = st_create();
	if (snum == NULL)
		exit(1);
	sop = st_create();
	if (sop == NULL)
		exit(1);

	while(str[i] != '\0')
	{
		if(str[i] > '0' &&str[i] < '9')
		{
			value = value * 10 + (str[i]- '0');
			flag = 1;
		}
		else // is a op
		{
			if (flag)
			{
				st_push(snum,&value);
				flag = 0;
				value = 0;
			}
			if(str[i] == ')')
			{
				deal_bracket(snum,sop);
			}
			else // ( + - * /
			{
				deal_op(snum,sop,str[i]);
			}
		}

		i++;
	}

	//处理 str[i-1]
	if (flag) //str[i-1]为数字
		st_push(snum,&value);//压入snum栈

	datatype old_op;
	int ret_num = 0;
	while(!st_isempty(sop))
	{
		st_pop(sop,&old_op);
		compute(snum,&old_op);//未完成!!!
		st_pop(snum,&ret_num);
	}

	printf("ret_num:%d\n",ret_num);//23

	st_destroy(snum);
	st_destroy(sop);

	exit(0);
}
